package com.ruoyi.bulkegg.controller;

import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.itextpdf.text.DocumentException;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.ZipExcelRefineModifier;
import com.ruoyi.bulkegg.service.ISupplyRelationCompanyService;
import com.ruoyi.bulkegg.domain.SupplyRelationCompany;
import com.ruoyi.common.utils.file.ZipExcelUtil;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.bulkegg.domain.OrderFileProcessRecord;
import com.ruoyi.bulkegg.service.IOrderFileProcessRecordService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
import lombok.extern.slf4j.Slf4j;

import static org.apache.commons.lang3.StringUtils.isNumeric;

/**
 * 供应商订单处理记录Controller
 *
 * @author ruoyi
 * @date 2025-09-28
 */
@Slf4j
@RestController
@RequestMapping("/bulkegg/orderfilerecord")
public class OrderFileProcessRecordController extends BaseController {
    @Autowired
    private IOrderFileProcessRecordService orderFileProcessRecordService;

    @Autowired
    private ISupplyRelationCompanyService supplyRelationCompanyService;

    /**
     * 查询供应商订单处理记录列表
     */
    @PreAuthorize("@ss.hasPermi('bulkegg:orderfilerecord:list')")
    @GetMapping("/list")
    public TableDataInfo list(OrderFileProcessRecord orderFileProcessRecord) {
        startPage();
        List<OrderFileProcessRecord> list = orderFileProcessRecordService.selectOrderFileProcessRecordList(orderFileProcessRecord);
        return getDataTable(list);
    }

    /**
     * 导出供应商订单处理记录列表
     */
    @PreAuthorize("@ss.hasPermi('bulkegg:orderfilerecord:export')")
    @Log(title = "供应商订单处理记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, OrderFileProcessRecord orderFileProcessRecord) {
        List<OrderFileProcessRecord> list = orderFileProcessRecordService.selectOrderFileProcessRecordList(orderFileProcessRecord);
        ExcelUtil<OrderFileProcessRecord> util = new ExcelUtil<OrderFileProcessRecord>(OrderFileProcessRecord.class);
        util.exportExcel(response, list, "供应商订单处理记录数据");
    }

    /**
     * 获取供应商订单处理记录详细信息
     */
    @PreAuthorize("@ss.hasPermi('bulkegg:orderfilerecord:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(orderFileProcessRecordService.selectOrderFileProcessRecordById(id));
    }

    /**
     * 新增供应商订单处理记录
     */
    @PreAuthorize("@ss.hasPermi('bulkegg:orderfilerecord:add')")
    @Log(title = "供应商订单处理记录", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody OrderFileProcessRecord orderFileProcessRecord) {
        return toAjax(orderFileProcessRecordService.insertOrderFileProcessRecord(orderFileProcessRecord));
    }

    /**
     * 修改供应商订单处理记录
     */
    @PreAuthorize("@ss.hasPermi('bulkegg:orderfilerecord:edit')")
    @Log(title = "供应商订单处理记录", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody OrderFileProcessRecord orderFileProcessRecord) {
        return toAjax(orderFileProcessRecordService.updateOrderFileProcessRecord(orderFileProcessRecord));
    }

    /**
     * 删除供应商订单处理记录
     */
    @PreAuthorize("@ss.hasPermi('bulkegg:orderfilerecord:remove')")
    @Log(title = "供应商订单处理记录", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(orderFileProcessRecordService.deleteOrderFileProcessRecordByIds(ids));
    }

    /**
     * 上传并处理
     */
    @Log(title = "供应商订单批量上传记录", businessType = BusinessType.OTHER)
    @PostMapping("/uploadZip")
    public AjaxResult uploadZip(@RequestParam("file") MultipartFile file) throws IOException, DocumentException {

        String originFile = FileUploadUtils.upload(RuoYiConfig.getProfile() + "/bulkegg/origin", file);
        // 1.大宗鸡蛋保存原始压缩包
        String originAbs = RuoYiConfig.getProfile() + originFile.replace("profile/", ""); //将系统增加出来的/profile文件夹虚拟路径替换掉

        // 2. 解压 + 处理
        String day = new java.text.SimpleDateFormat("yyyyMMdd").format(new Date());
        String processedDir = RuoYiConfig.getProfile() + "/bulkegg/processed/" + day + "/" + System.currentTimeMillis();
        List<String> sheetFilters = Arrays.asList(
                ".*结算.*",   // 结算单
                ".*发货.*",   // 发货单
                ".*采购.*",    // 采购单
                ".*sheet.*"   //sheet
        );


        Map<String, String> resultMap = ZipExcelRefineModifier.modify(
                originAbs,// 1.大宗鸡蛋保存原始压缩包
                processedDir, //输出目录（会生成同名新 zip）
                sheetFilters,           // 只改 Sheet 名含“结算”的 Excel
                ".*单.*"           // 只改表头含“总价”
        );

        // 从结果Map中获取targetDir值
        String targetDir = resultMap.get("targetDir");
        // 从结果Map中获取supplierCompany值
        String supplierCompany = resultMap.get("supplierCompany");

        // 根据supplierCompany查询SupplyRelationCompany记录
        Long supplyRelationCompanyId = Long.valueOf(1); // 默认值
        if (supplierCompany != null && !supplierCompany.trim().isEmpty()) {
            try {
                SupplyRelationCompany relationCompany = supplyRelationCompanyService.selectSupplyRelationCompanyBySupplierCompany(supplierCompany);
                if (relationCompany != null) {
                    supplyRelationCompanyId = relationCompany.getCompanyId();
                }
            } catch (Exception e) {
                // 查询异常时使用默认值
                log.error("根据供应商公司名称查询关系记录失败: {}", e.getMessage());
            }
        }
        // 3. 落库
        OrderFileProcessRecord record = new OrderFileProcessRecord();
        record.setOriginPath(originAbs);
        record.setTargetPath(targetDir);
        record.setSupplyRelationCompanyId(supplyRelationCompanyId);
        record.setCreateBy(SecurityUtils.getUsername());
        orderFileProcessRecordService.insertOrderFileProcessRecord(record);

        return AjaxResult.success("上传并处理完成");
    }

    /**
     * 下载原始压缩包
     */
    @PreAuthorize("@ss.hasPermi('bulkegg:orderfilerecord:download')")
    @GetMapping("/downloadZip")
    public void downloadZip(String fileName, HttpServletResponse response) throws IOException {
        // 1. 校验输入参数
        if (StringUtils.isEmpty(fileName)) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "文件名不能为空");
            return;
        }

        // 2. 构建完整文件路径（根据uploadZip方法的逻辑，文件应该在bulkegg/origin目录下）
        String filePath = fileName;
        File file = new File(filePath);

        // 检查文件是否存在
        if (!file.exists() || !file.isFile()) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "文件不存在");
            return;
        }

        // 3. 设置响应头信息，触发浏览器下载
        response.reset();
        response.setContentType("application/zip");
        response.setCharacterEncoding("utf-8");
        // 对文件名进行URL编码，以处理包含中文或特殊字符的情况
        String encodedFileName = URLEncoder.encode(file.getName(), "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"");
        response.setContentLengthLong(file.length());

        // 4. 将文件内容写入响应输出流
        try (BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(file.toPath()));
             ServletOutputStream os = response.getOutputStream()) {
            byte[] buffer = new byte[4096];
            int len;
            while ((len = bis.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            os.flush();
        } catch (Exception e) {
            logger.error("下载文件失败", e);
            throw e;
        }
    }

    private void zipFolderRecursively(File root, File current, java.util.zip.ZipOutputStream zos) throws IOException {
        File[] files = current.listFiles();
        if (files == null) return;
        for (File f : files) {
            if (f.isDirectory()) {
                zipFolderRecursively(root, f, zos);
            } else {
                String entryName = root.toPath().relativize(f.toPath()).toString().replace('\\', '/');
                zos.putNextEntry(new java.util.zip.ZipEntry(entryName));
                try (FileInputStream fis = new FileInputStream(f)) {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = fis.read(buffer)) != -1) {
                        zos.write(buffer, 0, bytesRead);
                    }
                }
                zos.closeEntry();
            }
        }
    }
}
